package easyBD;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;

import hardBD.AudioLoaderV2;

public class BeatDetect {
	private int seconds = 5;
	private int offset = 0;
	public BeatDetect(String filePath){
		//byte[] track = new AudioLoaderV2().load(filePath);
		byte[] track = new AudioLoaderV2().load60();
		Sample[] samples = new Sample[seconds * 43];
		
		//load array from data into samples
		int count = 0;
		byte[] tt = new byte[43*seconds*1024];

		int ctt = 0;
		for(int y = offset; y < offset + (seconds * 43 * 1024); y++){
			tt[ctt] = track[y];
			ctt++;
		}
		
		for(int i = offset; i < offset + (seconds * 43 * 1024); i += 1024){
			
			double[] audioSample = new double[1024];
			for(int j = 0; j < 1024; j++){
				audioSample[j] = track[i+j];
			}
			double time = offset/44100.0 + (((i-offset)/1024.0)/60);
			samples[count] = new Sample(audioSample,i, time);
			count++;
		}
		
		int ct = 0;
		for(Sample s : samples){
			
		}
		
		
		
		//run all the energy calculations
		for(int i = 0; i < samples.length; i++){
			calculateInstEnergy(samples[i]);
		}
		
		//Arraylist to store spikes
		ArrayList<Sample> spikes = new ArrayList<Sample>();
		
		//compare instant energies to local average to find spikes
		for(int i = 0; i < samples.length; i += 43){
			Sample[] tempSamples = new Sample[43];
			for(int j = 0; j < 43; j++){
				tempSamples[j] = samples[i+j];
			}
			double avg = calculateLocalAverage(tempSamples);
			double variance = calculateVariance(tempSamples);
			double threshold = calculateThreshold(variance);
			System.out.println(threshold);
			for(Sample temp : tempSamples){
				if(temp.energy > Math.abs(threshold)){
					spikes.add(temp);
				}
			}
		}
		
		System.out.println(samples.length);
		System.out.println(spikes.size());

		System.out.println(offset);
		for(Sample s : spikes){		
			System.out.print(s.index + " , ");
		}
		System.out.println("\n");
		System.out.println(samples[214].index);
		
		for(Sample s : spikes){	
			System.out.print(s.time + " , ");		
		}
		
		
		
		
		
		File out = new File("1.wav");
		FileOutputStream ff = null;
		try {
			ff = new FileOutputStream(out);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			ff.write(tt);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}
	
	public BeatDetect(String filePath, int seconds, int offset){
		//byte[] track = new AudioLoaderV2().load(filePath);
		byte[] track = new AudioLoaderV2().load60();
		this.seconds = seconds;
		this.offset = offset;
		Sample[] samples = new Sample[seconds * 43];
		
	}
	
	public double calculateVariance(Sample[] samples){
		double avg = calculateLocalAverage(samples);
		double result = 0;
		for(int i = 0; i < 43; i++){
			result += Math.pow((samples[i].energy-avg), 2);
		}
		return result / 43.0;
	}
	
	public double calculateThreshold(double variance){
		
		return (-0.0025714 * variance) + 1.5142857;
		
	}
	
	public double calculateInstEnergy(Sample sample){
		double result = 0.0;
		double[] samples = sample.audioSample;
		for(double tmp : samples){
			result += Math.pow((tmp),2);
		}
		sample.energy = result;
		return result;
	}
	
	public double calculateLocalAverage(Sample[] samples){
		double result = 0.0;
		for(Sample temp : samples){
			result += Math.pow(temp.energy, 2);
		}
		return result / 43.0;
	}
}
